package notesDetection.wavPackage;

import java.io.File;
import java.util.List;

import notesDetection.Utilities.NoteInfo;
import notesDetection.Utilities.SegmentNotesInfo;

public class WavExport {
	
	private long _sampleRate;
	//private double _windowLengthSec;
	
	public WavExport(long sampleRate, double windowLengthSec)
	{
		_sampleRate = sampleRate;
		//_windowLengthSec = windowLengthSec;
	}
	
	public void CreateWavFromCompressedData(List<SegmentNotesInfo> segmentsData, long sampleRate, double windowLengthSec, long numberOfFrames, String outputFileName) throws Exception
	{
		
		//	Evaluate total size:
		int totalFrames = 0;
		for(SegmentNotesInfo segment : segmentsData)
		{
			totalFrames += segment.getSegmentLength();
		}
		
		int numChannels = 1;
		File outputFile = new File(outputFileName);
		if(outputFile.exists())
		{
			if(!outputFile.delete())
			{
				throw new Exception("Output file already exist!");
			}
		}
		int validBits = 32;	//	Informational data only. STUB used
		WavFile outWavFile = WavFile.newWavFile(outputFile, numChannels, totalFrames, validBits, _sampleRate);


		//System.err.println("Total frames: " + totalFrames);
        
		//	frames per second
		//int segmentSize = (int) Math.round(_sampleRate * _windowLengthSec);
		double[] buffer = new double[totalFrames];
	    

        int currentSegmentOffset = 0;
        
        for(SegmentNotesInfo segment : segmentsData)
        {
        	decompressSegment(buffer, segment, currentSegmentOffset);
           // Write the buffer
        	outWavFile.writeFrames(buffer, currentSegmentOffset, segment.getSegmentLength());
        	
        	currentSegmentOffset += segment.getSegmentLength();
        }
		
		// Close the wavFile
		outWavFile.close();

	}

	private void decompressSegment(double[] buffer,
			SegmentNotesInfo segment, int bufferOffset) {
		
		for(NoteInfo note : segment.getNotesData())
		{
			decompressNote(buffer, note, bufferOffset, segment.getSegmentLength());
		}
		
	}

	private void decompressNote(double[] buffer, NoteInfo note, int bufferOffset, int segmentLength) { 

		for(int bufferIndex = bufferOffset; bufferIndex < bufferOffset + segmentLength; bufferIndex++)
		{
			double sineArgument = 2 * Math.PI * note.getNoteFrequency() / _sampleRate * (bufferIndex - bufferOffset) + note.getPhase();
			buffer[bufferIndex] += note.getAmplitude() * Math.sin(sineArgument);
		}
	}
	
}
